package com.letv.core.download.image;

import java.io.File;

import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;

import com.letv.android.sdk.R;
import com.letv.core.download.image.BitmapCache.CacheType;
import com.letv.core.utils.BaseTypeUtils;
import com.letv.core.utils.FileUtils;
import com.letv.core.utils.StoreUtils;

/**
 * 图片管理器
 * 
 * @author zhuqiao
 *
 */
public class ImageDownloader {
    public static final int PLACEHOLD_NULL = -2;

    private static ImageDownloader instance;
    private static ImageRequestQueue mRequestQueue;

    private Context mContext;
    private BitmapCache mCache;// 缓存

    /**
     * 下载配置
     * 
     * @author zhuqiao
     *
     */
    public static class DownloadConfig {
        public final CacheType cacheType;
        public final int memorySize;
        public final int threadCount;

        public DownloadConfig(CacheType cacheType, int memorySize) {
            this.cacheType = cacheType;
            this.memorySize = memorySize;
            threadCount = 3;
        }

        public DownloadConfig(int memorySize) {
            this(CacheType.SOFT, memorySize);
        }
    }

    /**
     * 图片配置
     * 
     * @author zhuqiao
     *
     */
    public static class BitmapConfig {
        public final int width;
        public final int height;

        public BitmapConfig(int width, int height) {
            this.width = width;
            this.height = height;
        }

    }

    /**
     * 图片下载信息
     * 
     * @author zhuqiao
     *
     */
    public static class DownloadRequest implements Comparable<DownloadRequest> {
        public final String url;
        public final View view;
        public final ImageDownloadStateListener listener;
        public final BitmapConfig config;

        /** 请求的序列号，用来执行FIFO **/
        private Integer mSequence;

        /** 请求队列 **/
        private ImageRequestQueue mQueue;

        /** 获取到的图片 **/
        private Bitmap mBitmap;

        /** 是否已被取消下载 **/
        private boolean mIsCanceled = false;

        public DownloadRequest(String url, View view, ImageDownloadStateListener listener, BitmapConfig config) {
            this.url = url;
            this.view = view;
            this.listener = listener;
            this.config = config;
        }

        public void setSequence(int sequence) {
            mSequence = sequence;
        }

        public int getSequence() {
            return mSequence;
        }

        public void setQueue(ImageRequestQueue queue) {
            mQueue = queue;
        }

        public void setBitmap(Bitmap bitmap) {
            mBitmap = bitmap;
        }

        public Bitmap getBitmap() {
            return mBitmap;
        }

        public void cancel() {
            mIsCanceled = true;
        }

        public boolean isCanceled() {
            return mIsCanceled;
        }

        public void finish() {
            if (mQueue != null) {
                mQueue.finish(this);
            }
        }

        @Override
        public int compareTo(DownloadRequest another) {
            return mSequence - another.mSequence;
        }
    }

    private ImageDownloader(Context context) {
        mContext = context;
        closeCache();
        init();
    }

    public static synchronized ImageDownloader getInstance(Context context) {
        if (instance == null) {
            instance = new ImageDownloader(context.getApplicationContext());
        }
        instance.setContext(context.getApplicationContext());

        if (mRequestQueue == null || !mRequestQueue.isRunning()) {
            instance.init();
        }
        return instance;
    }

    private void setContext(Context context) {
        mContext = context;
    }

    private void init() {
        mCache = new BitmapCache(mContext);
        mRequestQueue = new ImageRequestQueue(mCache);
        mRequestQueue.start();
    }

    /**
     * 销毁
     */
    public void onDestory() {
        mRequestQueue.stop();
        mCache.clearMemoryCache();
        instance = null;
    }

    /**
     * 将缓存记录同步到journal文件中。
     */
    public void fluchCache() {
        if (mCache != null && mCache.getDiscCache() != null) {
            mCache.getDiscCache().fluchCache();
        }
    }

    public void closeCache() {
        if (mCache != null && mCache.getDiscCache() != null) {
            mCache.getDiscCache().closeCache();
        }
    }

    /**
     * 下载图片
     * 
     * @param url 图片地址
     */
    public void download(String url) {
        download(null, url, null, -1, ScaleType.CENTER, true, null);
    }

    /**
     * 下载图片并且渲染view
     * 
     * @param view
     * @param url
     */
    public void download(View view, String url) {
        download(view, url, null, -1, ScaleType.CENTER, true, null);
    }

    /**
     * 下载图片并回调
     * 
     * @param url
     * @param listener
     */
    public void download(String url, ImageDownloadStateListener listener) {
        download(null, url, listener, -1, ScaleType.CENTER, true, null);
    }

    /**
     * 下载图片并且渲染view,下载成功前设置placeholder
     * 
     * @param view
     * @param url
     * @param placeholder
     */
    public void download(View view, String url, int placeholder) {
        download(view, url, null, placeholder, ScaleType.CENTER, true, null);
    }

    /**
     * 下载图片并且渲染view,下载成功前设置placeholder,并且设置placeholder的scaleType
     * 
     * @param view
     * @param url
     * @param placeholder
     * @param placeScaleType
     */
    public void download(View view, String url, int placeholder, ScaleType placeScaleType) {
        download(view, url, null, placeholder, placeScaleType, true, null);
    }

    /**
     * 下载图片并且渲染view,下载成功前设置placeholder,并且设置imageview的scaleType.当缓存中没有图片的时候设置是否下载
     * 
     * @param view
     * @param url
     * @param placeholder
     * @param downLoad
     */
    public void download(View view, String url, int placeholder, boolean downLoad) {
        download(view, url, null, placeholder, ScaleType.CENTER, downLoad, null);
    }

    /**
     * 下载图片并且渲染view,下载成功前设置placeholder.设置图片显示的宽高
     * 
     * @param view
     * @param url
     * @param placeholder
     * @param config
     */
    public void download(View view, String url, int placeholder, BitmapConfig config) {
        download(view, url, null, placeholder, ScaleType.CENTER, true, config);
    }

    /**
     * 加载图片
     * 
     * @param view 需要填充的view
     * @param url 图片地址
     * @param listener 回调接口
     * @param placeholder 占位图
     * @param placeScaleType 占位图scaleType
     * @param downLoad 当缓存中没有图片，是否从服务器上下载
     */
    @SuppressLint("InlinedApi")
    public void download(View view, String url, ImageDownloadStateListener listener, int placeholder,
            ScaleType placeScaleType, boolean downLoad, BitmapConfig config) {
        if (TextUtils.isEmpty(url)) {
            callback(listener, null, ImageDownloadStateListener.LOAD_ERROR);
            return;
        }

        if (view != null) {
            view.setTag(R.id.view_tag, url);
        }

        callback(listener, null, ImageDownloadStateListener.LOADING);

        Bitmap bitmap = null;

        if (mCache != null) {
            bitmap = mCache.getBitmapFromMemoryCache(url);
        }

        if (bitmap != null) {
            setBitmapForView(view, bitmap, url);
            callback(listener, bitmap, ImageDownloadStateListener.LOAD_SUCCESS);
        } else {
            // 当内存里没有这张图的时候，先设置可能的占位图
            setPlaceHolder(view, placeholder, placeScaleType);

            if (!downLoad) {
                return;
            }

            mRequestQueue.add(new DownloadRequest(url, view, listener, config));
        }
    }

    /**
     * 设置占位图
     */
    @SuppressWarnings("deprecation")
    private void setPlaceHolder(View view, int placeholder, ScaleType placeScaleType) {
        if (view == null)
            return;

        if (placeholder > 0) {
            if (view instanceof ImageView) {
                ((ImageView) view).setScaleType(placeScaleType);
                ((ImageView) view).setImageResource(placeholder);
            } else {
                view.setBackgroundResource(placeholder);
            }
        } else if (placeholder == PLACEHOLD_NULL) {
            if (view instanceof ImageView) {
                ((ImageView) view).setImageBitmap(null);
            } else {
                view.setBackgroundDrawable(null);
            }
        }
    }

    /**
     * 回调
     * 
     * @param listener
     */
    static void callback(ImageDownloadStateListener listener, Bitmap bitmap, int status) {
        if (listener == null)
            return;

        if (status == ImageDownloadStateListener.LOADING) {
            listener.loading();
        } else if (status == ImageDownloadStateListener.LOAD_SUCCESS) {
            if (bitmap != null && bitmap.isRecycled())
                bitmap = null;
            listener.loadSuccess(bitmap);
        } else {
            listener.loadFailed();
        }
    }

    /**
     * 给view设置图片
     * 
     * @param view
     * @param bitmap
     * @param url
     */
    @SuppressWarnings("deprecation")
    static void setBitmapForView(View view, Bitmap bitmap, String url) {
        if (view == null || bitmap == null || TextUtils.isEmpty(url) || bitmap.isRecycled())
            return;

        if (view.getTag(R.id.view_tag) == null || !view.getTag(R.id.view_tag).toString().equals(url))
            return;

        if (view instanceof ImageView) {
            ImageView imageView = (ImageView) view;
            if (imageView.getTag(R.id.scale_type) instanceof ScaleType) {
                imageView.setScaleType((ScaleType) imageView.getTag(R.id.scale_type));
            } else {
                imageView.setScaleType(ScaleType.FIT_XY);
            }
            imageView.setImageBitmap(bitmap);
        } else {
            view.setBackgroundDrawable(new BitmapDrawable(bitmap));
        }
    }

    /**
     * 取消下载.如果url为空,那么代表取消所有
     * 
     * @param url
     */
    public void cancel(String url) {
        if (mRequestQueue != null) {
            mRequestQueue.cancel(url);
        }
    }

    /**
     * 删除指定文件夹
     * */
    public static void deleteAllFile(final Context context, final CleanCacheListener listener) {
        if (!StoreUtils.isSdcardAvailable()) {
            listener.onErr();
            return;
        }

        Thread t = new Thread(new Runnable() {

            @Override
            public void run() {
                File display = new File(FileUtils.getBitmapCachePath(context));
                if (!display.exists()) {
                    listener.onNull();
                    return;
                }
                listener.onStar();

                File[] items = display.listFiles();
                if (BaseTypeUtils.isArrayEmpty(items)) {
                    listener.onComplete();
                    return;
                }

                int i = items.length;
                for (int j = 0; j < i; j++) {
                    if (items[j].isFile()) {
                        items[j].delete();
                    }
                }
                listener.onComplete();
            }
        });
        t.start();
    }

    /**
     * 清除缓存的监听器
     * */
    public interface CleanCacheListener {

        void onStar();

        void onComplete();

        void onErr();

        void onNull();
    }
}
